package com.yk._03Condition实现精准唤醒;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

public class Condition1 {

    public static void main(String[] args) {
        Resource resource = new Resource();
        new Thread(() -> {
            for (int i = 0; i < 151; i++) {
                resource.printA();
            }
        }, "线程A").start();
        new Thread(() -> {
            for (int i = 0; i < 15145; i++) {
                resource.printB();
            }
        }, "线程B").start();
        new Thread(() -> {
            for (int i = 0; i < 15185; i++) {
                resource.printC();
            }

        }, "线程C").start();
    }


}

class Resource {

    public final ReentrantLock lock = new ReentrantLock();


    public final Condition conditionA = lock.newCondition();
    public final Condition conditionB = lock.newCondition();
    public final Condition conditionC = lock.newCondition();

    public volatile String TMP = "A";

    public void printA() {
        lock.lock();
        try {
            while (!TMP.equalsIgnoreCase("A")) {
                conditionA.await();
            }
            System.out.println(Thread.currentThread().getName() + "  A");
            TMP = "B";
            conditionB.signal();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    public void printB() {

        lock.lock();
        try {
            while (!TMP.equalsIgnoreCase("B")) {
                conditionB.await();
            }
            System.out.println(Thread.currentThread().getName() + "  B");
            TMP = "C";
            conditionC.signal();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }

    }

    public void printC() {
        lock.lock();
        try {
            while (!TMP.equalsIgnoreCase("C")) {
                conditionC.await();
            }
            System.out.println(Thread.currentThread().getName() + "  C");
            TMP = "A";
            conditionA.signal();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }
}
